from django.core.paginator import Paginator, EmptyPage
from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django.http import JsonResponse
from django.conf import settings
import pytz

from index.utils import get_menu
from .utils import get_breadcrumb
from .models import *
from meiduo.utils.response_code import RETCODE


class GoodsDetail(View):
    """商品细节视图"""
    def get(self,request,good_id,page_num):
        sort_word = request.GET.get("sort")
        try:
            # 验证校验数据
            cat3 = GoodsCategory.objects.get(id=good_id)
        except GoodsCategory.DoesNotExist:
            return render(request, "404.html")
        if sort_word == "price":
            sort = "price"
        elif sort_word== "hot":
            sort = "-sales"
        else:
            sort_word = "default"
            sort = "-create_time"

        sku = SKU.objects.filter(category=cat3,is_launched=True).order_by(sort)

        paginator = Paginator(sku,5)
        try:
            pages_sku = paginator.page(page_num)
        except EmptyPage:
            return render(request,"404.html")
        total_page = paginator.num_pages
        context = {
            "good_all_kinds": get_menu(),
            "breadcrumb":get_breadcrumb(cat3),
            "category":{
                "id":good_id,
            },
            "page_skus":pages_sku,
            "sort":sort_word,
            "page_num":page_num,
            "total_page":total_page,


        }
        return render(request,"list.html",context)


class HotGoodsList(View):
    """热销排行列表"""
    def get(self,request,good_id):
        try:
            cat3 = GoodsCategory.objects.get(id=good_id)
        except GoodsCategory.DoesNotExist:
            return render(request,"404.html")
        skus = SKU.objects.filter(category=cat3,is_launched=True).order_by("-sales")[:2]
        data_list = list()

        for sku in skus:
            data_list.append(
                {"id":sku.id,
                 "name":sku.name,
                 'default_image_url':sku.default_image.url,
                 "price":sku.price}
            )
        return JsonResponse({"code":RETCODE.OK,"errnsg":"ok","hot_skus":data_list})


class GoodDetailShow(View):
    """商品详情显示"""
    def get(self,request,good_id):
        try:
            sku = SKU.objects.get(id=good_id)
        except SKU.DoesNotExist:
            return render(request, '404.html')

        category = sku.category  # 获取当前sku所对应的三级分类

        # 查询当前sku所对应的spu
        spu = sku.spu

        """1.准备当前商品的规格选项列表 [8, 11]"""
        # 获取出当前正显示的sku商品的规格选项id列表
        current_sku_spec_qs = sku.specs.order_by('spec_id')
        current_sku_option_ids = []  # [8, 11]
        for current_sku_spec in current_sku_spec_qs:
            current_sku_option_ids.append(current_sku_spec.option_id)

        """2.构造规格选择仓库
        {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8}
        """
        # 构造规格选择仓库
        temp_sku_qs = spu.sku_set.all()  # 获取当前spu下的所有sku
        # 选项仓库大字典
        spec_sku_map = {}  # {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8}
        for temp_sku in temp_sku_qs:
            # 查询每一个sku的规格数据
            temp_spec_qs = temp_sku.specs.order_by('spec_id')
            temp_sku_option_ids = []  # 用来包装每个sku的选项值
            for temp_spec in temp_spec_qs:
                temp_sku_option_ids.append(temp_spec.option_id)
            spec_sku_map[tuple(temp_sku_option_ids)] = temp_sku.id

        """3.组合 并找到sku_id 绑定"""
        spu_spec_qs = spu.specs.order_by('id')  # 获取当前spu中的所有规格

        for index, spec in enumerate(spu_spec_qs):  # 遍历当前所有的规格
            spec_option_qs = spec.options.all()  # 获取当前规格中的所有选项
            temp_option_ids = current_sku_option_ids[:]  # 复制一个新的当前显示商品的规格选项列表
            for option in spec_option_qs:  # 遍历当前规格下的所有选项
                temp_option_ids[index] = option.id  # [8, 12]
                option.sku_id = spec_sku_map.get(tuple(temp_option_ids))  # 给每个选项对象绑定下他sku_id属性

            spec.spec_options = spec_option_qs  # 把规格下的所有选项绑定到规格对象的spec_options属性上

        # 渲染页面
        context = {
            "good_all_kinds": get_menu(),# 查询商品频道分类
            'breadcrumb': get_breadcrumb(category),
            'sku': sku,  # 当前要显示的sku模型对象
            'category': category,  # 当前的显示sku所属的三级类别
            'spu': spu,  # sku所属的spu
            'spec_qs': spu_spec_qs,  # 当前商品的所有规格数据
        }
        return render(request,"detail.html",context)


class GoodDetailVisit(View):
    """统计每个商品日访问量"""
    def post(self,request,category_id):
        try:
            # 验证数据正确性
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return render(request,"404.html")

        # 查看数据库有无记录
        time_now = timezone.now()
        local_time = time_now.astimezone(pytz.timezone(settings.TIME_ZONE))
        date = local_time.date()
        try:
            # 有记录  在count上加一
            good_visit = GoodsVisitCount.objects.get(category_id=category_id,date=date)
        except GoodsVisitCount.DoesNotExist:
            good_visit = GoodsVisitCount(category_id=category_id)
        # 无记录  创建记录并加一
        good_visit.count += 1
        good_visit.save()

        return JsonResponse({"code":RETCODE.OK,"errmsg":"ok"})


